﻿using Nop.Core.Domain.Security;
using Nop.Services.Customers;
using Nop.Services.Security;
using Nop.Web.Models.Security;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Nop.Web.Controllers
{
    public class SecurityController : Controller
    {
        #region Fields
        private readonly ICustomerService _customerService;
        private readonly IPermissionAntService _permissionAntService;
        #endregion

        #region Ctor
        public SecurityController(ICustomerService customerService,
            IPermissionAntService permissionAntService)
        {
            this._customerService = customerService;
            this._permissionAntService = permissionAntService;
        }
        #endregion

        #region Utilities

        [NonAction]
        protected virtual List<MenuAuthorityModel> PrepareMenuAuthorityModel(List<Permission> lists, int parentId)
        {
            var menuAuths = new List<MenuAuthorityModel>();
            var permissions = lists.Where(m => m.ParentId == parentId).ToList();
            foreach (var item in permissions)
            {
                var menuAuth = new MenuAuthorityModel();
                menuAuth.name = item.SystemName;
                menuAuth.authority = item.CustomerRoles.Select(x => x.SystemName).ToList();
                menuAuth.children = PrepareMenuAuthorityModel(lists, item.Id);
                menuAuths.Add(menuAuth);
            }
            return menuAuths;
        }

        [NonAction]
        protected virtual List<MenuModel> PrepareMenuModel(List<Permission> lists, int parentId)
        {
            var menuAuths = new List<MenuModel>();
            var permissions = lists.Where(m => m.ParentId == parentId).ToList();
            foreach (var item in permissions)
            {
                var menuAuth = new MenuModel();
                menuAuth.key = item.Id.ToString();
                menuAuth.title = item.Name;
                menuAuth.children = PrepareMenuModel(lists, item.Id);
                menuAuths.Add(menuAuth);
            }
            return menuAuths;
        }

        #endregion

        /// <summary>
        /// 获取菜单权限
        /// 前台通过该返回结果生成菜单及权限验证
        /// </summary>
        /// <returns></returns>
        public JsonResult GetMenuAuthorityData()
        {
            var permissions = _permissionAntService.GetAllPermissions().Where(m => m.Active).ToList();
            var model = PrepareMenuAuthorityModel(permissions, 0);
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 菜单列表
        /// </summary>
        /// <returns></returns>
        public JsonResult GetMenuList()
        {
            var permissions = _permissionAntService.GetAllPermissions().Where(m => m.Active).ToList();
            var model = PrepareMenuModel(permissions, 0);
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 获取角色已有权限的菜单Id
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public JsonResult GetCheckMenuKeys(int roleId)
        {
            var model = new List<string>();
            var role = _customerService.GetCustomerRoleById(roleId);
            if (role != null)
                model = role.Permissions.Select(x => x.Id.ToString()).ToList();
            return Json(model, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 保存角色权限
        /// </summary>
        /// <param name="guid">用户身份验证</param>
        /// <param name="roleId"></param>
        /// <param name="defaultCheckKeys"></param>
        /// <returns></returns>
        public JsonResult SetCheckMenuKeys(string guid, int roleId, int[] checkKeys)
        {
            if (!_permissionAntService.Authorize(guid, (int)PermissionAntEnum.permissions))
                return Json(new { result = false, msg = "无权访问" });
            var permissions = _permissionAntService.GetAllPermissions().Where(m => m.Active).ToList();
            var role = _customerService.GetCustomerRoleById(roleId);
            if (role != null)
            {
                if (checkKeys!=null&&checkKeys.Length>0)
                {
                    foreach (var p in permissions)
                    {
                        if (checkKeys.Contains(p.Id))
                        {
                            if (role.Permissions.FirstOrDefault(x => x.Id == p.Id) == null)
                            {
                                role.Permissions.Add(p);
                            }
                        }
                        else
                        {
                            if (role.Permissions.FirstOrDefault(x => x.Id == p.Id) != null)
                            {
                                role.Permissions.Remove(p);
                            }
                        }
                    }
                }
                else
                {
                    role.Permissions.Clear();
                }
                _customerService.UpdateCustomerRole(role);
            }
            return Json(new { result = true }, JsonRequestBehavior.AllowGet);
        }
    }
}